﻿#region copyright
/*
* Copyright (c) 2009, Dion Kurczek
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of the <organization> nor the
*       names of its contributors may be used to endorse or promote products
*       derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY DION KURCZEK ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL DION KURCZEK BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#endregion

using System;
using System.Collections.Generic;
using System.Text;
using SCG.General;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.Windows;
using System.Drawing;
using SCG.WinForms;

namespace SCG.Prism
{
    //Represents user information for a connected client.  Fields can map to a database or other
    //form of storage, based on the PrismServerStorage-derived class implemented in the server.
    public class PrismUser
    {
        //Constructor
        public PrismUser()
        {
        }

        //User Name is a unique string "handle" of this user  
        public string UserName
        {
            get
            {
                return _userName;
            }
            set
            {
                _userName = value;
            }
        }

        //User's password
        public string Password
        {
            get
            {
                return _password;
            }
            set
            {
                _password = value;
            }
        }

        //Date user was first established
        public DateTime CreationDate
        {
            get
            {
                return _creationDate;
            }
            set
            {
                _creationDate = value;
            }
        }

        //Login information
        public DateTime LastLoginDate
        {
            get
            {
                return _lastLoginDate;
            }
            set
            {
                _lastLoginDate = value;
            }
        }
        public int LoginCount
        {
            get
            {
                return _loginCount;
            }
            set
            {
                _loginCount = value;
            }
        }

        //Descriptive information common to all users
        public string FullName
        {
            get
            {
                return _fullName;
            }
            set
            {
                _fullName = value;
            }
        }
        public string Email
        {
            get
            {
                return _email;
            }
            set
            {
                _email = value;
            }
        }
        public string Profile
        {
            get
            {
                return _profile;
            }
            set
            {
                _profile = value;
            }
        }
        public string Location
        {
            get
            {
                return _location;
            }
            set
            {
                _location = value;
            }
        }
        public string WebSite
        {
            get
            {
                return _webSite;
            }
            set
            {
                _webSite = value;
            }
        }

        //Latency
        public int LatencyMS
        {
            get
            {
                return _latencyMS;
            }
            set
            {
                _latencyMS = value;
            }
        }

        //Details
        [XmlIgnore]
        public Dictionary<string, string> Details
        {
            get
            {
                return _details;
            }
            set
            {
                _details = value;
            }
        }

        //Allow Details to be serialized
        public string DetailString
        {
            get
            {
                Tokenizer tok = new Tokenizer();
                tok.AppendToken(Details.Count);
                foreach (KeyValuePair<string, string> kvp in Details)
                {
                    tok.AppendToken(kvp.Key);
                    tok.AppendToken(kvp.Value);
                }
                return tok.Result;
            }
            set
            {
                Tokenizer tok = new Tokenizer(value);
                int n = tok.TokenInt;
                while (n > 0)
                {
                    string key = tok.TokenString;
                    string val = tok.TokenString;
                    Details[key] = val;
                    n--;
                }
            }
        }

        //Details are ad-hoc name/value pairs that can store pieces of info about the user
        public string GetDetail(string Key)
        {
            if (_details.ContainsKey(Key))
                return _details[Key];
            else
                return "";
        }
        public void SetDetail(string Key, string Value)
        {
            _details[Key] = Value;
        }
        public int GetDetailInt(string key)
        {
            string s = GetDetail(key);
            if (s == "")
                return 0;
            try
            {
                return Int32.Parse(s);
            }
            catch
            {
                return 0;
            }
        }
        public void SetDetail(string key, int value)
        {
            SetDetail(key, value.ToString());
        }
        public double GetDetailDouble(string key)
        {
            string s = GetDetail(key);
            if (s == "")
                return 0;
            try
            {
                return Double.Parse(s, Tokenizer.CULTURE);
            }
            catch
            {
                return 0;
            }
        }
        public void SetDetail(string key, double value)
        {
            SetDetail(key, value.ToString());
        }     

        //Record the action of a user logging in
        public void RecordLogin()
        {
            _loginCount++;
            _lastLoginDate = DateTime.Now;
        }

        //rating support
        public double GetRating(string key, double minRating = 1200.0)
        {
            string s = GetDetail(key + "Rating");
            if (s == "")
                return minRating;
            else
                return Double.Parse(s);
        }
        public void SetRating(string key, double rating)
        {
            SetDetail(key + "Rating", rating.ToString());
        }

        //Presistence - Convert to a string
        public override string ToString()
        {
            Tokenizer tok = new Tokenizer();
            tok.Tokenize(UserName, Password, CreationDate, LastLoginDate, LoginCount, FullName,
                Location, WebSite, Email, Profile, GlyphString);
            tok.AppendToken(Details.Count);
            foreach (KeyValuePair<string, string> kvp in Details)
            {
                tok.AppendToken(kvp.Key);
                tok.AppendToken(kvp.Value);
            }
            return tok.Result;
        }

        //Populate from a string
        public void FromString(string s)
        {
            Tokenizer tok = new Tokenizer(s);
            UserName = tok.TokenString;
            Password = tok.TokenString;
            CreationDate = tok.TokenDateTime;
            LastLoginDate = tok.TokenDateTime;
            LoginCount = tok.TokenInt;
            FullName = tok.TokenString;
            Location = tok.TokenString;
            WebSite = tok.TokenString;
            Email = tok.TokenString;
            Profile = tok.TokenString;
            GlyphString = tok.TokenString;

            int n = tok.TokenInt;
            while (n > 0)
            {
                string key = tok.TokenString;
                string value = tok.TokenString;
                Details[key] = value;
                n--;
            }     
        }
        public void FromString(string s, bool fullCopy)
        {
            if (fullCopy)
                FromString(s);
            else
            {
                Tokenizer tok = new Tokenizer(s);
                UserName = tok.TokenString;
                Password = tok.TokenString;

                //avoid reloading creation date, last login date, and login count
                DateTime dt = tok.TokenDateTime;
                dt = tok.TokenDateTime;
                int i = tok.TokenInt;

                FullName = tok.TokenString;
                Location = tok.TokenString;
                WebSite = tok.TokenString;
                Email = tok.TokenString;
                Profile = tok.TokenString;
                GlyphString = tok.TokenString;

                int n = tok.TokenInt;
                while (n > 0)
                {
                    string key = tok.TokenString;
                    string value = tok.TokenString;
                    Details[key] = value;
                    n--;
                }    
            }
        }

        //Glyph
        private string _glyphString;
        public string GlyphString
        {
            get
            {
                return _glyphString;
            }
            set
            {
                _glyphString = value;
                if (value != null && value != "")
                    _glyph = ImageUtils.StringToImage(value);
            }
        }

        private Image _glyph = null;
        [XmlIgnore]
        public Image Glyph
        {
            get
            {
                return _glyph;
            }
            set
            {
                _glyph = value;
                if (value != null)
                    _glyphString = ImageUtils.ImageToString(value);
            }
        }

        //Private members
        private Dictionary<string, string> _details = new Dictionary<string, string>();       
        private string _userName = "";
        private DateTime _creationDate = DateTime.MinValue;
        private DateTime _lastLoginDate = DateTime.MinValue;
        private string _password = "";
        private int _loginCount = 0;
        private string _fullName = "";
        private string _location = "";
        private string _email = "";
        private string _profile = "";
        private string _webSite = "";
        private int _latencyMS = 0;
    }
}
